﻿Public Class Mastermind

    Private score As Integer = 0

    Private code(3) As String
    Private codePegs(9, 3) As String
    Private keyPegs(9, 3) As String

    Private maxTries As Integer = 10
    Private maxGames As Integer = 2
    Private activeGame As Integer
    Private activeRow As Integer

    Public Sub New()
        Initialize()
    End Sub

    Public Sub Initialize()
        activeGame = 1
        activeRow = 0
    End Sub

    Public Sub ResetGame()
        activeRow = 0

        For i As Integer = 0 To code.GetUpperBound(0)
            code(i) = Nothing
        Next

        For i As Integer = 0 To codePegs.GetUpperBound(0)
            For j As Integer = 0 To codePegs.GetUpperBound(1)
                codePegs(i, j) = Nothing
                keyPegs(i, j) = Nothing
            Next
        Next
    End Sub

    Public Function GetMaxTries() As Integer
        Return maxTries
    End Function

    Public Function GetScore() As Integer
        Return score
    End Function

    Public Sub IncreaseScore(ByVal value As Integer)
        score += value
    End Sub

    Public Function GetActiveGame() As Integer
        Return activeGame
    End Function

    Public Sub IncreaseActiveGame()
        activeGame += 1
    End Sub

    Public Function GetMaxGames() As Integer
        Return maxGames
    End Function

    Public Function GetCode() As String()
        Return code
    End Function

    Public Sub SetCode(ByVal array() As String)
        code = array
    End Sub

    Public Function GetCodePegBoard() As String(,)
        Return codePegs
    End Function

    Public Sub SetCodeRow(ByVal row As Integer, ByVal array() As String)
        codePegs(row, 0) = array(0)
        codePegs(row, 1) = array(1)
        codePegs(row, 2) = array(2)
        codePegs(row, 3) = array(3)
    End Sub

    Public Function GetKeyPegBoard() As String(,)
        Return keyPegs
    End Function

    Public Sub SetKeyRow(ByVal row As Integer, ByVal array() As String)
        keyPegs(row, 0) = array(0)
        keyPegs(row, 1) = array(1)
        keyPegs(row, 2) = array(2)
        keyPegs(row, 3) = array(3)
    End Sub

    Public Function GetRow() As Integer
        Return activeRow
    End Function

    Public Sub IncreaseRow()
        activeRow += 1
    End Sub

    Public Sub Reset()
        For i As Integer = 0 To keyPegs.GetUpperBound(1)
            keyPegs(activeRow, i) = "graySmall"
        Next
    End Sub

    Public Function Encode(ByVal array() As String) As String
        Dim message As String = ""

        For i As Integer = 0 To array.GetUpperBound(0)
            If Not array(i) Is Nothing Then
                If message = "" Then
                    message = array(i)
                Else
                    message += "." + array(i)
                End If

            End If
        Next

        Return message
    End Function

    Public Sub Decode(ByVal message As String, ByVal array(,) As String)

        Dim words() As String = message.Split(New Char() {"."c})

        If words.Length > 0 Then
            For i As Integer = 0 To words.Length - 1
                array(activeRow, i) = words(i)
            Next
        End If
    End Sub

    Public Function ValidateGuess() As Boolean
        For i As Integer = 0 To codePegs.GetUpperBound(1)
            If codePegs(activeRow, i) Is Nothing OrElse codePegs(activeRow, i) = "gray" Then
                Return False
            End If
        Next

        Return True
    End Function

    Public Function ValidateHints() As Boolean
        Dim temp(3) As String
        Dim counter As Integer = 0

        Dim guessIndexes(3) As Integer
        Dim codeIndexes(3) As Integer

        For i As Integer = 0 To codePegs.GetUpperBound(1)
            If codePegs(activeRow, i) = code(i) Then
                temp(counter) = "black"
                counter += 1
            Else
                guessIndexes(i) = i
                codeIndexes(i) = i
            End If
        Next

        For i As Integer = 0 To guessIndexes.GetUpperBound(0)
            If guessIndexes(i) <> Nothing Then
                For j As Integer = 0 To codeIndexes.GetUpperBound(0)
                    If codeIndexes(j) <> Nothing Then
                        If codePegs(activeRow, guessIndexes(i)) = code(codeIndexes(j)) Then
                            temp(counter) = "white"
                            counter += 1
                            codeIndexes(j) = Nothing
                            Exit For
                        End If
                    End If
                Next
            End If
        Next

        For i As Integer = 0 To temp.GetUpperBound(0)
            If temp(i) Is Nothing Then
                temp(i) = "graySmall"
            End If
        Next

        For i As Integer = 0 To keyPegs.GetUpperBound(1)
            'MsgBox(temp(i))
            If temp(i) = keyPegs(activeRow, i) Then
                Continue For
            Else
                Return False
            End If
        Next

        Return True
    End Function

    Public Function ValidateCode() As Boolean
        For i As Integer = 0 To code.GetUpperBound(0)
            If code(i) Is Nothing Or code(i) = "gray" Then
                Return False
            End If
        Next

        Return True
    End Function

    Public Function CheckWinCondition() As Boolean
        For i As Integer = 0 To code.GetUpperBound(0)
            If codePegs(activeRow, i) = code(i) Then
                Continue For
            Else
                Return False
            End If
        Next

        Return True
    End Function
End Class
